<template>
    <div class="marquee" ref="marquee">
        <div class="marquee-content">
            <slot></slot>
        </div>
        <div class="marquee-prev" @click.stop="prev"><</div>
        <div class="marquee-next" @click.stop="next">></div>
        <div class="marquee-pagination"></div>
    </div>
</template>

<script>
	export default {
		name: 'Marquee',
		data () {
			return {
				isMove: false,
				startX: 0,
				startY: 0,
				index: 0,
				maxIndex: 0,
				timeout: null
			};
		},
		props: {
			loop: {type: Boolean, default: false},
			loopTime: {type: Number, default: 5000}
		},
		methods: {
			onTouchStart (e) {
				this.isMove = true;
				this.startX = this.getIntervalWidth(this.index) + e.pageX;
				window.el = e;
			},
			onTouchMove (e) {
				if (this.isMove === false) return false;
				let m = e.pageX - this.startX;
				this.getEl().style.transitionDuration = '0ms';
				this.getEl().style.transform = 'translate3d(' + m + 'px,0,0)';
			},
			onTouchEnd (e) {
				this.isMove = false;
				let w = this.getIntervalWidth(this.index);
				console.log(w);
				this.getEl().style.transitionDuration = '300ms';
				this.getEl().style.transform = 'translate3d(' + w + 'px , 0, 0)';
				let x = Math.abs(e.pageX - this.startX);
				let contentWidth = this.$el.children[0].offsetWidth;
				if (x > contentWidth * 0.4) {
					this.next();
				}
			},
			preventClicks (e) {
				e.preventDefault();
				e.stopPropagation();
				e.stopImmediatePropagation();
				console.info('click');
				window.els = this.$el;
			},
			getEl () {
				return this.$el.children[0];
			},
			init () {
				this.computePagination();
				this.bindButton();
				this.addDefaultClass();
				this.setLoop();
			},
			computePagination () {
				let list = this.getEl();
				let count = list.childElementCount;
				let pagination = this.$el.getElementsByClassName('marquee-pagination')[0];
				if (pagination && pagination.length) {
					return;
				}
				let html = '';
				let w = this.$el.offsetWidth;
				for (let i = 0; i < count; i++) {
					html = `${html}<a data-index="${i}"></a>`;
					let mw = 0;
					for (let x = i; x < count; x++) {
						mw += list.children[x].offsetWidth + 30;
					}
					if (mw < w) {
						this.maxIndex = i + 1;
						break;
					} else {
						this.maxIndex = count;
					}
				}
				pagination.innerHTML = html;
			},
			prev () {
				this.index--;
				if (this.index < 0) {
					this.index = this.maxIndex - 1;
				}
				this.switchPage(this.index);
			},
			next () {
				this.index++;
				if (this.index >= this.maxIndex) {
					this.index = 0;
				}
				this.switchPage(this.index);
			},
			bindButton () {
				this.$el.getElementsByClassName('marquee-pagination')[0].addEventListener('click', this.changePage);
			},
			changePage (e) {
				this.switchPage(e.srcElement.getAttribute('data-index'));
			},
			switchPage (index) {
				if (index >= this.maxIndex) return false;
				let w = this.getIntervalWidth(index);
				this.removeActive();
				this.$el.querySelector('.marquee-pagination > a[data-index="' + index + '"]').className = 'active';
				let content = this.getEl();
				content.style.transitionDuration = '500ms';
				content.style.transform = 'translate3d(-' + w + 'px , 0, 0)';
				content.children[this.index].style.transitionDuration = '200ms';
				content.children[this.index].style.transform = 'scale(.3, .3)';
				setTimeout(() => {
					content.children[this.index].style.transform = 'scale(1, 1)';
                }, 300);
				this.index = index;
				this.setLoop();
			},
			removeActive () {
				let list = this.$el.querySelectorAll('.marquee-pagination > a');
				if ((list && list.length) === false) return;
				for (let index in list) {
					if (index >= 0) {
						list[index].className = '';
					}
				}
			},
			addDefaultClass () {
				this.$nextTick(() => {
					let el = this.$el.querySelector('.marquee-pagination > a[data-index="0"]');
					if (el !== null) {
						el.className = 'active';
					}
				});
			},
			update () {
				this.unBind();
				this.init();
			},
			unBind () {
				this.$el.getElementsByClassName('marquee-pagination')[0].removeEventListener('click', this.changePage);
			},
			setLoop () {
				this.clearTime();
				if (this.loop === true) {
					this.timeout = setInterval(() => {
						this.next();
					}, this.loopTime);
				}
			},
			clearTime () {
				if (this.timeout !== null) {
					clearInterval(this.timeout);
					this.timeout = null;
				}
			},
			getIntervalWidth (index) {
				let content = this.getEl();
				let w = 0;
				for (let i = 0; i < index; i++) {
					w = w + content.children[i].offsetWidth + 30;
				}
				if (index === 0) {
					w = 0;
				}
				return w;
			}
		},
		mounted () {
			this.$el.children[0].addEventListener('mousedown', this.onTouchStart);
			this.$el.children[0].addEventListener('mousemove', this.onTouchMove);
			this.$el.children[0].addEventListener('mouseup', this.onTouchEnd);
			this.init();
		}
	};
</script>

<style>
    .marquee {
        margin-left: auto;
        margin-right: auto;
        position: relative;
        overflow: hidden;
        z-index: 1;
    }

    .marquee-content {
        position: relative;
        width: auto;
        height: auto;
        display: flex;
        /*cursor: pointer;*/
    }

    .marquee-next, .marquee-prev {
        background-color: rgba(0, 0, 0, .5);
        position: absolute;
        width: 50px;
        height: 50px;
        line-height: 50px;
        top: 50%;
        margin-top: -25px;
        cursor: pointer;
        text-align: center;
        color: white;
        font-size: 30px;
    }

    .marquee-prev {
        left: 0;
    }

    .marquee-next {
        right: 0;
    }

    .marquee-pagination {
        height: auto;
        width: 100%;
        position: absolute;
        bottom: 10px;
        left: 0;
        text-align: center;
    }

    .marquee-pagination > a {
        display: inline-block;
        width: 15px;
        height: 15px;
        background-color: white;
        margin: 0 3px;
        border-radius: 50%;
        cursor: pointer;
        border: 1px solid #737373;
    }

    .marquee-pagination > a.active {
        background-color: #737373;
    }
</style>
